/**
 * 
 */
package jvs.core.http.handler;


import java.io.InputStream;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;

import jvs.core.http.Request;
import jvs.core.http.Response;
import jvs.core.http.Utils;
import jvs.tea.html.Constant;
import jvs.tea.html.FileTypeTemplateInputStream;
import jvs.vfs.io.CounterInputStream;
import x.java.io.File;
import x.java.io.FileWriter;

/**
 * @author qiangli
 * 
 */
public class BinHandler extends FileHandler {
	private static final SimpleDateFormat cdf = new SimpleDateFormat(
			"yyyy-MM-dd.HH.mm.ss.SSS");
	
	//private static final String THUMBNAIL_IMAGE_TYPE = "jpg";

	protected void binHtm(Request req, Response res, File file) throws Exception {
		if (file == null || file.isDirectory()) {
			URI uri = new URI("http://"+req.host+"/");
			if (file != null) {
				uri = uri.resolve(file.getPath());
			}
			res.redirect(uri);
			return;
		}
		res.statusCode = Response.CODE200;
		res.contentType = Response.TYPE_TEXT_HTML;
		res.lastModified = System.currentTimeMillis(); //?
		res.date = System.currentTimeMillis();
		res.transferEncoding = Response.TRANSFER_ENCODING_CHUNKED;
		InputStream is = new FileTypeTemplateInputStream(req.context.baseUri, file);
		res.send(is, true);
	}

	protected void binPlayback(Request req, Response res, File file) throws Exception {
		String type = guessType(file);
		res.statusCode = Response.CODE200;
		res.contentType = type;
		res.lastModified = file.lastModified();
		res.date = System.currentTimeMillis();
		res.transferEncoding = Response.TRANSFER_ENCODING_CHUNKED;
		InputStream is = createFileInputStream(file);
		res.send(is, true);
	}

	private void binPost(Request req, Response res, File file) throws Exception {
		String fp = file.getPath();
		System.err.println("comment fp: " + fp);
		// got comment?
		String cmt = req.getParam("comment");
		if (file.isFile() && cmt != null && cmt.trim().length() > 0) {
			File cfp = createFile(Constant.COMMENT_MP + fp);
			System.err.println("comment path: " + cfp);
			cfp.mkdirs();
			Date now = new Date();
			String date = cdf.format(now);
			String fn = date + ".txt";
			File cf = new x.java.io.File(cfp, fn);
			FileWriter fw = new FileWriter(cf);
			fw.write(nvl(date) + "\r\n");
			fw.write("\r\n");
			fw.write(cmt);
			fw.close();
		}
		redirect(req, res);
	}

	protected void binThumbnail(Request req, Response res, File file) throws Exception {
		String type = guessType(file);
		res.statusCode = Response.CODE200;
		res.contentType = type;
		res.lastModified = file.lastModified();
		res.date = System.currentTimeMillis();
		res.transferEncoding = Response.TRANSFER_ENCODING_CHUNKED;
		InputStream is = createFileInputStream(file);
		res.send(is, true);
		///ChunkedOutputStream cos = new ChunkedOutputStream(res.os, false);
		//TODO 
		//int min = 120;
		//int max = 150;
		//scaleImage(is, cos, min, max);
		//copy(is,cos);
		//is.close();
		//cos.close();
	}

	/**
	 * @param req
	 * @param res
	 * @throws Exception
	 */
	protected void doBin(Request req, Response res) throws Exception {
		String fp = req.getParam("filepath");
		//
		fp = Utils.parsePath(fp);
		//path must be local
		File f = (fp == null) ? null : createFile(fp);
		String p = req.path; ////req.requestUri.indexOf('?');
		int idx = p.indexOf('?'); 
		String bin = (idx == -1) ? p : p.substring(0, idx);
		
		//do internal bin
		if (bin.equals("/bin/htm")) {
			binHtm(req, res, f);
			return;
		}
		
		if (bin.equals("/bin/post")) {
			binPost(req, res, f);
			return;
		}
		
		if (bin.equals("/bin/thumbnail")) {
			binThumbnail(req, res, f);
			return;
		}
	
		if (bin.equals("/bin/head")) {
			binHead(req, res, f);
			return;
		}
		
		if (bin.equals("/bin/playback")) {
			binPlayback(req, res, f);
			return;
		}
		throw new Exception("invalid bin path: "+req.requestUri);
	}


	protected void binHead(Request req, Response res, File file) throws Exception {
		int maxbyte = 256;
		try {
			maxbyte = Integer.parseInt(req.getParam("maxbyte"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		String type = guessType(file);
		res.statusCode = Response.CODE200;
		res.contentType = type;
		res.lastModified = file.lastModified();
		res.date = System.currentTimeMillis();
		res.transferEncoding = Response.TRANSFER_ENCODING_CHUNKED;
		
		//writeHeader(res.os,Response.CODE200, type, new Date(file.lastModified()), new Date());
		InputStream is = new CounterInputStream(createFileInputStream(file),maxbyte);
		res.send(is, true);
		//ChunkedOutputStream cos = new ChunkedOutputStream(res.os, false);
		//copy(is, cos);
		//is.close();
		//cos.close();
	}

	private void redirect(Request req, Response res) throws Exception {
		URI uri = new URI(req.referer);
		res.redirect(uri);
	}

	@Override
	public boolean handle(Request req, Response res) {
		if (isBinRequest(req)) {
			try {
				doBin(req, res);
			} catch (Exception e) {
				res.error(e);
			}
			return true;
		}

		return false;
	}

	protected boolean isBinRequest(Request req) {
		// /bin/.* length > 5
		return (req.path.startsWith("/bin/") && req.path.length() > 5);
	}
}
